package com.easy.system.dao.impl;

import com.easy.system.dao.BaseDao;
import com.easy.system.util.HibernateBeanReflectUtil;
import com.easy.system.util.Pagination;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import java.sql.SQLException;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: sunguangzhu
 * Date: 13-6-18
 * Time: 下午1:20
 * To change this template use File | Settings | File Templates.
 */
@Repository
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
    @Override
    public void save(T entity) {
        this.getHibernateTemplate().save(entity);
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void update(T entity) {
        this.getHibernateTemplate().update(entity);
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void delete(T entity) {
        this.getHibernateTemplate().delete(entity);
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public int delete(Class<T> clazz, String ids) {
        final StringBuilder sql = new StringBuilder();
        String tableName = HibernateBeanReflectUtil.getTableName(clazz);
        sql.append(" delete from ").append(tableName).append(" where id in ( ").append(ids).append(" )");
        return this.getHibernateTemplate().execute(new HibernateCallback<Integer>() {
            @Override
            public Integer doInHibernate(Session session) throws HibernateException, SQLException {
                SQLQuery sqlQuery = session.createSQLQuery(sql.toString());
                return sqlQuery.executeUpdate();
            }
        });
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public T get(Class<T> clazz, Long id) {
        return this.getHibernateTemplate().get(clazz, id);  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public List<T> find(final String hql, final Pagination pagination, final Object... params) {
        return (List<T>) this.getHibernateTemplate().execute(new HibernateCallback() {
            public List<T> doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                if (params != null) {
                    query = createQueryParams(query, params);
                }
                if (pagination != null) {
                    query.setFirstResult(pagination.getFirstTotal());
                    query.setMaxResults(pagination.getPageSize());
                }
                return query.list();
            }
        });
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public List<T> find(String hql, Pagination pagination) {
        return this.find(hql, pagination, null);  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Long getTotal(final String hql, final Object... params) {
        return (Long) this.getHibernateTemplate().execute(new HibernateCallback() {
            public Long doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                if (params != null) {
                    query = createQueryParams(query, params);
                }
                return (Long) query.uniqueResult();
            }
        });
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Long getTotal(final String hql) {
        return this.getTotal(hql, null);
        //To change body of implemented methods use File | Settings | File Templates.
    }

    private Query createQueryParams(Query query, Object... params) {
        for (int i = 0; params != null && i < params.length; i++)
            query.setParameter(i, params[i]);
        return query;
    }


}
